package cn.liurong.com.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

/**
 * Http请求工具类
 * 
 * @author 刘荣
 * @date 2017年5月2日 
 */
public class HttpUtils {
	private static final Logger logger = Logger.getLogger(HttpUtils.class);
	private static final String GET = "GET";
	private static final String POST = "POST";
	/**
	 *  1.text/html
	 * 2.text/plain
	 * 3.text/css
	 * 4.text/javascript
	 * 5.application/x-www-form-urlencoded
	 * 6.multipart/form-data
	 * 7.application/json
	 * 8.application/xml
	 */
	private static final String CONTENT_TYPE = "application/x-www-form-urlencoded";

	public static String httpGet(String urlString, int... timeouts) {
		logger.info("接收到httpGet请求，请求url为：" + urlString);
		HttpURLConnection httpURLConnection = null;
		StringBuffer result = null;
		BufferedReader reader = null;
		InputStreamReader inputStreamReader = null;
		InputStream inputStream = null;
		String line = null;
		int timeout = 0;
		if (timeouts != null && timeouts.length > 0) {
			timeout = timeouts[0];
		} else {
			timeout = 3000;
		}
		try {
			// 得到connection
			httpURLConnection = getHttpUrlConnection(urlString);
			// 设置请求信息
			setRequestInfo(httpURLConnection, HttpUtils.GET, timeout);

			// 建立连接
			httpURLConnection.connect();
			// 如果返回成功
			if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
				// 得到请求结果
				inputStream = httpURLConnection.getInputStream();
				inputStreamReader = new InputStreamReader(inputStream);
				reader = new BufferedReader(inputStreamReader);
				result = new StringBuffer();
				while ((line = reader.readLine()) != null) {
					result.append(line);
				}
			}
		} catch (Exception e) {
			logger.error("发送Get请求抛出异常" + e);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					logger.error("关闭BufferedReader流抛出异常" + e);
				}
			}
			if (inputStreamReader != null) {
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					logger.error("关闭InputStreamReader流抛出异常" + e);
				}
			}
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					logger.error("关闭InputStream流抛出异常" + e);
				}
			}
		}
		return result != null ? result.toString() : "";
	}

	public static String htttpPost(String urlString, Map<String, String> paramsMap, int... timeouts) {
		logger.info("接收到post请求 urlString=" + urlString + ",paramsMap=" + paramsMap + ",timeouts=" + timeouts);
		HttpURLConnection httpUrlConnection = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader bufferedReader = null;
		String line = null;
		StringBuffer result = new StringBuffer();
		try {
			// 得到连接
			httpUrlConnection = getHttpUrlConnection(urlString);
			int timeout = 0;
			if (timeouts != null && timeouts.length > 0) {
				timeout = timeouts[0];
			} else {
				timeout = 3000;
			}
			// 设置请求信息
			setRequestInfo(httpUrlConnection, HttpUtils.POST, timeout);
			// 获取连接
			httpUrlConnection.connect();
			// 设置请求参数
			writeRequestInfo(httpUrlConnection, paramsMap);
			// 如果返回成功
			if (httpUrlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
				// 得到响应结果
				inputStream = httpUrlConnection.getInputStream();
				inputStreamReader = new InputStreamReader(inputStream);
				bufferedReader = new BufferedReader(inputStreamReader);
				while ((line = bufferedReader.readLine()) != null) {
					result.append(line);
				}
			}
		} catch (IOException e) {
			logger.error("发送post请求抛出异常：" + e.toString() + e.getMessage());
		} finally {
			// 关闭响应流
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					logger.error("关闭BufferedReader流抛出异常" + e);
				}
			}
			if (inputStreamReader != null) {
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					logger.error("关闭InputStreamReader流抛出异常" + e);
				}
			}
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					logger.error("关闭InputStream流抛出异常" + e);
				}
			}
		}
		return result != null ? result.toString() : "";
	}

	private static void writeRequestInfo(HttpURLConnection httpUrlConnection, Map<String, String> paramsMap)
			throws IOException {
		if (paramsMap == null || paramsMap.size() < 1) {
			return;
		}
		PrintWriter printWriter = new PrintWriter(httpUrlConnection.getOutputStream());
		Set<String> keySet = paramsMap.keySet();
		StringBuffer paramBuff = new StringBuffer();
		for (String string : keySet) {
			paramBuff.append(string).append("=").append(URLEncoder.encode(paramsMap.get(string), "UTF-8")).append("&");
		}
		//去掉最后一个&
		String paramString = paramBuff.substring(0, paramBuff.length() - 1);
		logger.info("post请求请求体为：" + paramString);
		printWriter.write(paramString);
		printWriter.flush();
		printWriter.close();
	}

	private static HttpURLConnection getHttpUrlConnection(String urlString) throws IOException {
		URL url = new URL(urlString);
		URLConnection connection = url.openConnection();
		return (HttpURLConnection) connection;
	}

	private static void setRequestInfo(HttpURLConnection httpURLConnection, String requestMehod, int responseTimeout)
			throws ProtocolException {
		// 设置等待连接超时时间
		httpURLConnection.setConnectTimeout(5000);
		// 设置等待相应超时时间
		httpURLConnection.setReadTimeout(responseTimeout);
		if (requestMehod.equals(HttpUtils.POST)) {
			// 设置是否向httpUrlConnection输出(默认false)，post请求必须设置成true，因为post请求的参数在请求体中
			httpURLConnection.setDoInput(true);
		}
		// 设置是否从httpUrlConnection读入（默认true），获取响应信息，所以为默认肯定要获取
		httpURLConnection.setDoOutput(true);
		// 设置请求类型
		httpURLConnection.setRequestMethod(requestMehod);
		// 设置是否需要缓存
		httpURLConnection.setUseCaches(false);
		// 设置请求参数类型
		httpURLConnection.setRequestProperty("Content-type", HttpUtils.CONTENT_TYPE);
	}
}
